package start

import (
	"fmt"
	"net"

	"gitee.com/go-course/go9/tree/master/projects/vblog/api/apps"
	"gitee.com/go-course/go9/tree/master/projects/vblog/api/conf"
	"gitee.com/go-course/go9/tree/master/projects/vblog/api/logger"
	"gitee.com/go-course/go9/tree/master/projects/vblog/api/ui"
	"github.com/gin-gonic/gin"
	"github.com/spf13/cobra"
	"google.golang.org/grpc"
)

var (
	configType string
	filePath   string
)

// Start cmd
var Cmd = &cobra.Command{
	// 程序名称
	Use:     "start",
	Short:   "start vblog-api server",
	Long:    "启动服务",
	Example: "vblog-api start -f etc/config.toml",
	// 命令执行逻辑
	// The *Run functions are executed in the following order:
	//   * PersistentPreRun()
	//   * PreRun()
	//   * Run()
	//   * PostRun()
	//   * PersistentPostRun()
	// args: vblog-api start xxxx yyyy tttt
	// args: []{xxxx yyyy tttt}
	Run: func(cmd *cobra.Command, args []string) {
		// 加载程序配置
		switch configType {
		case "file":
			cmd.Println("load config from: ", filePath)
			err := conf.LoadConfigFromToml(filePath)
			cobra.CheckErr(err)
		case "env":
			cmd.PrintErr("not implement")
			return
		case "etcd":
			cmd.PrintErr("not implement")
			return
		default:
			cmd.PrintErr("unsport config type, support [file,env,etcd]")
			return
		}

		// 初始化托管类, 其他完成注册(init函数对象实例注册, 只需要import包)
		err := apps.InitApps()
		cobra.CheckErr(err)

		// 1. 注册http 实例类 import
		// 2. 初始化 所有注册的http 实例类
		server := gin.Default()

		// 前端配置Vite代理模式开发, 由于是服务端访问服务端, 不存在CORS问题
		// 由于是开发单体应用, 后端提供的API 就是给前端使用的, 因此可以不用开发跨域
		// 如果要开发跨域请求添加跨域中间件进行处理:
		// 全局中间件: 补充cors中间件
		// cm := cors.New(cors.Config{
		// 	AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
		// 	AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
		// 	AllowCredentials: true,
		// 	MaxAge:           12 * time.Hour,
		// 	AllowOrigins:     []string{"http://localhost:5173"},
		// })
		// server.Use(cm)

		// http 服务注册
		v1 := server.Group("/vblog/api/v1")
		err = apps.InitHttpApps(v1)
		cobra.CheckErr(err)

		// 补充UI
		ui.Registry(server)
		logger.L().Debug().Msgf("UI URL: http://localhost:8050/")

		// grpc 注册
		grpcServer := grpc.NewServer()
		err = apps.InitGrpcApps(grpcServer)
		cobra.CheckErr(err)

		lis, err := net.Listen("tcp", ":18050")
		cobra.CheckErr(err)

		// 然后通过grpcServer.Serve(lis)在一个监听端口上提供gRPC服务
		go grpcServer.Serve(lis)

		// 启动HTTP接口监听
		if err := server.Run(":8050"); err != nil {
			fmt.Println(err)
		}
	},
}

func init() {
	Cmd.Flags().StringVarP(&configType, "config-type", "t", "file", "选择程序加载配置的方式: [file,env,etcd]")
	Cmd.Flags().StringVarP(&filePath, "file-path", "f", "etc/config.toml", "配置文件路径")
}
